package com.pokermadness.servlets;

import java.io.IOException;
import java.util.HashMap;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;

import com.pokermadness.chat.Chat;

/**
 * Jetty WebSocketServlet implementation class ChatWebSocketServlet
 */
@WebServlet("/ChatWebSocketServlet")
public class ChatWebSocketServlet extends WebSocketServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see WebSocketServlet#WebSocketServlet()
     */
    public ChatWebSocketServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
	private final Set<ChatWebSocket> members = new CopyOnWriteArraySet<ChatWebSocket>();

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		getServletContext().getNamedDispatcher("default").forward(request, response);
	}
	
	/*
	 * @see org.eclipse.jetty.websocket.WebSocketServlet#doWebSocketConnect(javax.servlet.http.HttpServletRequest, java.lang.String)
	 */
	protected WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
		HttpSession session;
		@SuppressWarnings("unchecked")
		HashMap<String, HttpSession> map = (HashMap<String, HttpSession>) getServletContext()
				.getAttribute("active-sessions");
		String key = getCookieValue(request.getCookies(), "session", "-1");
		
		if (map.containsKey(key)) {
			session = map.get(key);
		} else {
			session = request.getSession(true);
			session.setMaxInactiveInterval(3600);
		}
		
		Chat chat = (Chat) session.getAttribute("chat");
		if (chat == null) {
			chat = new Chat();
			session.setAttribute("chat", chat);
		}
		
		return new ChatWebSocket(chat);
	}
	
	class ChatWebSocket implements WebSocket {
		private Outbound outbound;
		private Chat chat;
		
		public ChatWebSocket(Chat chat) {
			this.chat = chat;
		}

		public void onConnect(Outbound outbound) {
			this.outbound = outbound;
			members.add(this);
			Random random = new Random();
			while(true) {
				int delay = random.nextInt(120000) + 1000;
				try {
					Thread.sleep(delay);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				try {
					outbound.sendMessage(chat.getRandomMessage().toString());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		/*
		 * @see org.eclipse.jetty.websocket.WebSocket#onMessage(byte, byte[],
		 * int, int)
		 */
		public void onMessage(byte frame, byte[] data, int offset, int length) {
		}

		/*
		 * @see org.eclipse.jetty.websocket.WebSocket#onMessage(byte,
		 * java.lang.String)
		 */
		public void onMessage(byte frame, String data) {
			
			for (ChatWebSocket member : members) {
				try {
					member.outbound.sendMessage(frame, data);
				} catch (IOException e) {
					// org.eclipse.jetty.util.log.Log.warn(e);
					e.printStackTrace();
				}
			}
		}

		/*
		 * @see org.eclipse.jetty.websocket.WebSocket#onDisconnect()
		 */
		public void onDisconnect() {
			members.remove(this);
		}
		
		/*
		 * 
		 * @see org.eclipse.jetty.websocket.WebSocket#onFragment(boolean, byte,
		 * byte[], int, int)
		 */
		public void onFragment(boolean more, byte opcode, byte[] data,
				int offset, int length) {

		}
		
	}
	
	private String getCookieValue(Cookie[] cookies, String cookieName,
			String defaultValue) {
		if (cookies == null)
			return defaultValue;
		for (int i = 0; i < cookies.length; i++) {
			Cookie cookie = cookies[i];
			if (cookieName.equals(cookie.getName()))
				return (cookie.getValue());
		}
		return (defaultValue);
	}


}
